package main

import (
	"bufio"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"golang.org/x/net/html/charset"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

var (
	// 通道
	chDl = make(chan Dl, 10)
	targetURLS = []string{"http://www.mm131.com/xinggan/",
		"http://www.mm131.com/qingchun/",
		"http://www.mm131.com/xiaohua/",
		"http://www.mm131.com/chemo/",
		"http://www.mm131.com/qipao/",
		"http://www.mm131.com/mingxing/"}
)

func init() {
	go func() {
		for {
			dl := <-chDl

			go dlMedia(dl)
		}
	}()
}

func main() {

	//crawlPage("http://www.mm131.com/xinggan/")

	for i :=range targetURLS{
		go crawlPage(targetURLS[i],i)
	}

	//resp, err := http.Get("http://www.mm131.com/xinggan/")
	//if err != nil {
	//	fmt.Errorf("error %s \n",err)
	//	return
	//}
	//
	//bytes, err := ioutil.ReadAll(resp.Body)
	//
	//fmt.Printf("%s\n",string(bytes))

	select {}
}

// 超链接 src , 标题 , 防盗链
type Dl struct {
	src     string
	alt     string
	referer string
}

// 爬去页面,提取 mm 的链接 和分析下一页
func crawlPage(url string, index int ) {

	resp, err := http.Get(url)
	if err != nil {
		fmt.Printf("error %+v\n", err)
		return
	}
	newReader := bufio.NewReader(resp.Body)
	uEncoding := determineEncoding(newReader)
	determineReader := transform.NewReader(newReader, uEncoding.NewDecoder())

	doc, err := goquery.NewDocumentFromReader(determineReader)
	if err != nil {
		fmt.Printf("eror %s ",err)
	}

	doc.Find("dl.list-left dd a[target=_blank]").EachWithBreak(func(i int, selection *goquery.Selection) bool {
		value, ok := selection.Attr("href")
		fmt.Printf("index %+v value  = %+v ok %+v \n", i, value, ok)
		if ok {
			crawlPerson(value,index )
		}

		return true
	})

	nodes := doc.Find("dd.page span.page_now").Next()

	val, exists := nodes.Attr("href")
	fmt.Printf("exists := nodes.Attr(\"href\") value  = %+v exists %+v \n", val, exists)
	// 这里就要关闭流了
	resp.Body.Close()
	if exists {
		//crawlPage("http://www.mm131.com/xinggan/" + val)
		crawlPerson(targetURLS[index]+val, index )
	}

}

// 返回获取网页的编码
func determineEncoding(reader *bufio.Reader) (uEncoding encoding.Encoding) {
	data, err := reader.Peek(1024)

	if err != nil {
		return unicode.UTF8
	}

	uEncoding, _, _ = charset.DetermineEncoding(data, "")
	return uEncoding
}

func dlMedia(dl Dl) {
	fmt.Printf("dl media %+v\n", dl)
	req, _ := http.NewRequest("GET", dl.src, nil)

	req.Header.Add("cache-control", "no-cache")
	req.Header.Add("referer", dl.referer)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)
	paths  := strings.Split(dl.src, "/")
	os.Mkdir("./"+dl.alt,0766)
	file, err := os.OpenFile("./"+dl.alt+"/"+paths[len(paths) -1], os.O_CREATE|os.O_RDWR, 0766)
	if err != nil {
		fmt.Printf("erro %+v \n",err )
	}

	defer file.Close()
	fmt.Printf("code = %v  url = %s ,n",res.StatusCode,dl.src)

	fmt.Println(res.StatusCode)
	file.Write(body)
}

// 提取图片地址和 下一页
func crawlPerson(url string ,index int ) {

	resp, err := http.Get(url)
	if err != nil {
		fmt.Printf("error %+v\n", err)
		return
	}
	newReader := bufio.NewReader(resp.Body)
	uEncoding := determineEncoding(newReader)
	determineReader := transform.NewReader(newReader, uEncoding.NewDecoder())

	doc, err := goquery.NewDocumentFromReader(determineReader)
	fmt.Printf("crawlPerson %+v \n", url)

	//doc, err := goquery.NewDocument(url)

	if err != nil {
		fmt.Errorf("error %#v \n", err)
		return

	}
	src, ok := doc.Find("div.content-pic img").Attr("src")
	alt, _ := doc.Find("div.content-pic img").Attr("alt")


	fmt.Printf("src is %+v ok = %+v \n", src, ok)

	if ok {
		sps := strings.Split(alt, "(")
		// 截取图片的值
		if len(sps) == 2 {
			alt = sps[0]
		}
		//chDl <- Dl{src: src, referer: url, alt: alt}
		dlMedia(Dl{src: src, referer: url, alt: alt})
	}
	href, exists := doc.Find("div.content-page span.page_now").Next().Attr("href")
	// 关闭流对象
	resp.Body.Close()
	if exists {
		//crawlPerson("http://www.mm131.com/xinggan/" + href)
		crawlPerson(targetURLS[index]+href,index)
		fmt.Printf("exist %+v\n", href)
	} else {
		fmt.Printf("no exist %v \n", exists)
	}

}
